package scaladuct

import asm.JavaBean

/**
 * <p>
 * Created by IntelliJ IDEA.
 * User: zslajchrt
 * Date: Aug 7, 2010
 * Time: 11:15:14 AM
 */

object NullStarter extends Starter[Null] {
  def destroy(instance: Null) = {}

  def newInstance(): Null = null
}

class NoPage extends {
val id = "NoPage"
} with FinalPage[Null] {
  protected def consume() = NullStarter
}

abstract class OnePage(val next: ConfigPage[Null]) extends ConfigPage[Null] {
  val firstCookie: Cookie

  def getCookie() = firstCookie

  def consume(cookie: Cookie) = NextPage(next)
}

class StringOnePage extends {val id = "OnePage"} with OnePage(new NoPage) {
  type Cookie = String
  override val firstCookie = "ABC"
}

@JavaBean
class CompositeCookieSample(private var x: Int, private var y: String, private var z: Boolean) {
  def getX() = x

  def setX(xx: Int) = x = xx

  def getY() = y

  def setY(yy: String) = y = yy

  def getZ() = z

  def setZ(zz: Boolean) = z = zz

  override def toString = "x=" + x + " y=" + y + " z=" + z
}

class CookieStarter(val cookie: AnyRef) extends Starter[AnyRef] {
  def destroy(instance: AnyRef) = {}

  def newInstance(): AnyRef = null
}

class FinalPageWithCookieStarter extends FinalPage[Null] {
  val id = "FinalPageWithCookieStarter"

  protected def consume() = NullStarter
}

class CompositeCookiePage extends {val id = "CompositeCookiePage"
} with OnePage(new NoPage) {
  type Cookie = CompositeCookieSample
  override val firstCookie = new CompositeCookieSample(1, "aaa", false)
}

class PlainStarter[X](val x: X) extends Starter[X] {
  def destroy(instance: X) = null

  def newInstance() = x
}

class PageWithCookiesAsResult extends {val id = "PageWithCookiesAsResult"} with ConfigPage[CompositeCookieSample] {
  type Cookie = CompositeCookieSample


  val cookie = new CompositeCookieSample(1, "aaa", false)

  def getCookie() = cookie

  def consume(cookie: CompositeCookieSample): ConfigResult[CompositeCookieSample] = {
    NewStarter(new PlainStarter[CompositeCookieSample](cookie))
  }

}

class PageSeqWithCookiesAsResult(val index: Int,
                                 val count: Int,
                                 val cookies: List[CompositeCookieSample])
        extends {val id = "PageSeqWithCookiesAsResult" + index
        } with ConfigPage[List[CompositeCookieSample]] {
  type Cookie = CompositeCookieSample

  def this(count: Int) = this (0, count, List.empty)

  val cookie = initCookie

  private def initCookie(): CompositeCookieSample = {
    new CompositeCookieSample(index, "I" + index, index % 2 == 0)
  }

  def getCookie() = cookie

  def consume(cookie: CompositeCookieSample) = {
    if (index == count - 1) {
      NewStarter(new PlainStarter((cookie :: cookies).reverse))
    } else {
      NextPage(new PageSeqWithCookiesAsResult(index + 1, count, cookie :: cookies))
    }
  }


}